package ift605.tp3.utils.equations;

import ift605.tp3.utils.Token;

public class EquationUtility
{
    private static IEquation parse(Token p_token) throws UnknownEquationTypeException
    {
        if (p_token.length() == 0)
        {
            return new ConstantEq(0.0);
        }
        
        IEquation equation = null;
        double coefficient = 1.0;
        
        do
        {
            if (p_token.getToken() == '-' || p_token.getToken() == '.' || Character.isDigit(p_token.getToken()))
            {
                String tmp = "";
                do
                {
                    tmp += p_token.getToken();
                }
                while (p_token.nextToken() && (p_token.getToken() == '.' || Character.isDigit(p_token.getToken())));
                
                coefficient = Double.parseDouble(tmp);
            }
            else if (Character.toLowerCase(p_token.getToken()) == 'x')
            {
                p_token.nextToken(); // ^
                if (p_token.getToken() == null || p_token.getToken() != '^')
                {
                    equation = new VariableEq(coefficient);
                }
                else
                {
                    String tmp = "";
                    
                    if (p_token.nextToken() && (Character.isDigit(p_token.getToken()) || p_token.getToken() == '-'))
                    {
                        do
                        {
                            tmp += p_token.getToken();
                        }
                        while (p_token.nextToken() && Character.isDigit(p_token.getToken()));
                    }
                    
                    final int exponent = Integer.parseInt(tmp);
                    equation = new PowEq(coefficient, exponent);
                }
            }
            else if (p_token.getToken() == '+')
            {
                p_token.nextToken();
                final IEquation e = EquationUtility.parse(p_token);
                equation = new SummativeEq(equation, e);
            }
            else if (p_token.getToken() == '(')
            {
                p_token.nextToken();
                final IEquation e1 = EquationUtility.parse(p_token);
                
                String tmp = "";
                tmp += p_token.getToken();
                p_token.nextToken(); // )
                tmp += p_token.getToken();
                p_token.nextToken(); // (
                
                if (!tmp.equals(")("))
                {
                    throw new UnknownEquationTypeException();
                }
                
                final IEquation e2 = EquationUtility.parse(p_token);
                equation = new MultiplicativeEq(e1, e2);
                p_token.nextToken();
            }
            else if (p_token.getToken() == ')')
            {
                break;
            }
            else
            {
                p_token.nextToken();
            }
        }
        while (p_token.length() > 0);
        
        if (equation == null)
        {
            equation = new ConstantEq(coefficient);
        }
        
        return equation;
    }
    
    public static IEquation parse(String eq) throws UnknownEquationTypeException
    {
        return EquationUtility.parse(new Token(eq));
    }
}
